package org.haifi.game.action;

import org.apache.commons.lang.StringUtils;
import org.apache.mina.core.session.IoSession;
import org.haifi.game.AlertException;
import org.haifi.game.GameContext;
import org.haifi.game.GameException;
import org.haifi.game.GameString;
import org.haifi.game.annotation.MethodId;
import org.haifi.game.model.GameUser;
import org.haifi.game.pb.GameUserAction.CreateGuestUserMessage;
import org.haifi.game.pb.GameUserAction.CreateUserMessage;
import org.haifi.game.pb.GameUserAction.GameUserActionParam;
import org.haifi.game.pb.GameUserAction.LoginMessage;
import org.haifi.game.service.GameUserManager;
import org.haifi.game.service.WordFilterManager;
import org.haifi.game.util.GameUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 用户帐号相关接口
 * 
 * 协议id: 1~50
 * 
 * 每个action中保留50个methodId,理论上应该是足够用的。
 * 
 * @author joycube2
 * 
 */
@Component
public class GameUserAction extends GameBaseAction {

	/**
	 * 创建帐号
	 * 
	 * <p>
	 * 帐号不可为空，长度6~32
	 * <p>
	 * 密码不可为空，长度6~20
	 * 
	 * @param 协议号
	 *            1
	 * @param username
	 *            帐号名
	 * @param password
	 *            密码
	 * @return
	 */
	@MethodId(1)
	public CreateUserMessage.Builder createNewUser(GameUserActionParam param) {

		String username = param.getUsername();
		String password = param.getPassword();

		CreateUserMessage.Builder message = CreateUserMessage.newBuilder();
		if (!GameContext.isGateWay()) {
			// 只有网关上允许创建新帐号
			throw new AlertException(GameException.PERMISSION_DENNIED);
		}
		if (StringUtils.isEmpty(username) || username.length() < 6
				|| username.length() > 32) {
			// 帐号不可为空，长度6~32
			message.setInfo(GameException.GAME_USER_NAME_ERROR_1);
			return message;
		}
		if (StringUtils.isEmpty(password) || password.length() < 6
				|| password.length() > 20) {
			// 密码不可为空，长度6~20
			message.setInfo(GameException.GAME_PASSWORD_ERROR);
			return message;
		}
		// 验证是否有过滤字
		if (wordFilterManager.isNameDirty(username)) {
			message.setInfo(GameException.GAME_USER_NAME_ERROR_2);
			return message;
		}
		// 验证是否重名
		if (gameUserManager.getByName(username) != null) {
			message.setInfo(GameException.GAME_USER_NAME_ERROR_3);
			return message;
		}

		// 创建帐号
		gameUserManager.createNewUser(username, password);
		// 创建帐号后，直接是登陆状态
		
		message.setUsername(username);
		return message;
	}

	/**
	 * 登陆
	 * 
	 * @param 协议号
	 *            2
	 * @param username
	 *            帐号名
	 * @param password
	 *            密码
	 */
	@MethodId(2)
	public LoginMessage.Builder login(GameUserActionParam param) {
		String username = param.getUsername();
		String password = param.getPassword();

		LoginMessage.Builder message = LoginMessage.newBuilder();
		if (!GameContext.isGateWay()) {
			// 只有网关上允许登陆
			throw new AlertException(GameException.PERMISSION_DENNIED);
		}
		if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
			// 帐号名或密码为空
			message.setInfo(GameException.GAME_USER_NAME_OR_PASSWORD_IS_NULL);
			return message;
		}
		GameUser gameUser = gameUserManager.getByName(username);
		if (gameUser == null) {
			// 帐号不存在
			message.setInfo(GameException.GAME_USER_NAME_OR_PASSWORD_ERROR);
			return message;
		}
		// 验证密码
		String encodePassword = gameUserManager.encodePassword(password);
		if (!encodePassword.equals(gameUser.getPassword())) {
			// 密码错误
			message.setInfo(GameException.GAME_USER_NAME_OR_PASSWORD_ERROR);
			return message;
		}

		// 当前的ioSession
		IoSession ioSession = getCurrentSession();
		gameUserManager.login(ioSession, gameUser);

		return message;
	}

	/**
	 * 创建匿名帐号
	 * 
	 * <p>
	 * 调用此接口成功后，玩家默认已经使用创建的帐号登陆。客户端可以不必再次调用登陆接口进行登陆。
	 * 
	 * @param 协议号
	 *            3
	 */
	@MethodId(3)
	public CreateGuestUserMessage.Builder createGuestUser(
			GameUserActionParam param) {
		CreateGuestUserMessage.Builder message = CreateGuestUserMessage
				.newBuilder();
		if (!GameContext.isGateWay()) {
			// 统一异常机制完成　
			// // 只有网关上允许用户登陆
			// // TODO:这里需要改为统一处理机制，只有和游戏本攻击提示相关的提示才应该放在message中
			// message.setInfo(GameException.PERMISSION_DENNIED);
			// return message;
			// // 应该有一种机制，允许抛出全局异常，也就是说一个全局处理的方式
			throw new AlertException(GameException.PERMISSION_DENNIED);
		}

		// 帐号随机
		String username = GameString.GUEST_NAME + "$"
				+ System.currentTimeMillis() / 1000000
				+ GameUtil.nextInt(100000);

		// 密码：6位随机数
		String password = "" + 100000 + GameUtil.nextInt(800000);
		GameUser gameUser = gameUserManager.createNewUser(username, password);
		// 创建成功后直接登陆
		IoSession ioSession = getCurrentSession();
		gameUserManager.login(ioSession, gameUser);

		message.setUsername(username);
		message.setPassword(password);
		return message;
	}

	/**
	 * 绑定匿名帐号
	 * 
	 * @param 协议号
	 *            4
	 */
	@MethodId(4)
	public void bingGuestUser(GameUserActionParam param) {
		if (!GameContext.isGateWay()) {
			// 只有网关上允许绑定匿名帐号
			throw new AlertException(GameException.PERMISSION_DENNIED);
		}
	}

	/**
	 * 修改密码
	 * 
	 * @param 协议号
	 *            5
	 */
	@MethodId(5)
	public void changePassword(GameUserActionParam param) {
		if (!GameContext.isGateWay()) {
			// 只有网关上允许修改密码
			throw new AlertException(GameException.PERMISSION_DENNIED);
		}
	}

	/**
	 * 使用token登陆
	 * 
	 * 免用户名密码登陆，只要token认证通过即认为登陆成功
	 * 
	 * 如果游戏服重启了，这里可以传一个token，用来让用户直接登陆，而无需再次进行登陆
	 * 
	 * @param 协议号
	 *            6
	 */
	@MethodId(6)
	public void tokenLogin(GameUserActionParam param) {
		if (!GameContext.isGameServer()) {
			// 只有游戏服上允许使用token登陆
			throw new AlertException(GameException.PERMISSION_DENNIED);
		}
	}

	@Autowired
	private GameUserManager gameUserManager;

	@Autowired
	private WordFilterManager wordFilterManager;
}
